import os
import re
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path as MplPath
from matplotlib.patches import PathPatch
import xml.etree.ElementTree as ET
from svgpathtools import svg2paths2

def parse_rgb(style):
    match = re.search(r'fill:rgb\(([\d.%]+),([\d.%]+),([\d.%]+)\)', style)
    if match:
        r, g, b = match.groups()
        if '%' in r:
            return tuple(float(c.strip('%')) / 100 for c in (r, g, b))
        else:
            return tuple(float(c) / 255 for c in (r, g, b))
    match_hex = re.search(r'fill:\s*#([0-9a-fA-F]{6})', style)
    if match_hex:
        hex_color = match_hex.group(1)
        r = int(hex_color[0:2], 16) / 255
        g = int(hex_color[2:4], 16) / 255
        b = int(hex_color[4:6], 16) / 255
        return (r, g, b)
    return (0, 0, 0)  # 默认黑色

# 主处理函数
def process_svg(svg_file, output_folder):
    with open(svg_file, 'r', encoding='utf-8') as f:
        content = f.read()

    width_match = re.search(r'width="([\d.]+)(?:pt|px)?"', content)
    height_match = re.search(r'height="([\d.]+)(?:pt|px)?"', content)
    fig_width, fig_height = 10, 10
    if width_match and height_match:
        fig_width = float(width_match.group(1))
        fig_height = float(height_match.group(1))

    paths, attrs, svg_attr = svg2paths2(svg_file)
    fig, ax = plt.subplots(figsize=(fig_width, fig_height))
    ax.set_aspect('equal')
    ax.set_facecolor('white')

    for path, attr in zip(paths, attrs):
        style = attr.get("style", "")
        fill_color = parse_rgb(style)
        verts = []
        codes = []
        for i, segment in enumerate(path):
            if i == 0:
                verts.append((segment.start.real, segment.start.imag))
                codes.append(MplPath.MOVETO)
            verts.append((segment.end.real, segment.end.imag))
            codes.append(MplPath.LINETO)
        if verts:
            mpl_path = MplPath(verts, codes)
            patch = PathPatch(mpl_path, facecolor=fill_color, edgecolor='none')
            ax.add_patch(patch)

    # 手动解析 <path> 元素（包含贝塞尔曲线）
    tree = ET.parse(svg_file)
    root = tree.getroot()
    for elem in root.iter('{http://www.w3.org/2000/svg}path'):
        d = elem.attrib.get('d', '')
        style = elem.attrib.get('style', "")
        fill_color = parse_rgb(style)
        path_data = d.split()
        verts = []
        codes = []
        i = 0
        while i < len(path_data):
            cmd = path_data[i]
            if cmd == 'M':
                x, y = float(path_data[i + 1]), float(path_data[i + 2])
                verts.append((x, y))
                codes.append(MplPath.MOVETO)
                i += 3
            elif cmd == 'L':
                x, y = float(path_data[i + 1]), float(path_data[i + 2])
                verts.append((x, y))
                codes.append(MplPath.LINETO)
                i += 3
            elif cmd == 'C':
                x1, y1 = float(path_data[i + 1]), float(path_data[i + 2])
                x2, y2 = float(path_data[i + 3]), float(path_data[i + 4])
                x3, y3 = float(path_data[i + 5]), float(path_data[i + 6])
                verts.extend([(x1, y1), (x2, y2), (x3, y3)])
                codes.extend([MplPath.CURVE4] * 3)
                i += 7
            elif cmd in ['Z', 'z']:
                verts.append((0, 0))
                codes.append(MplPath.CLOSEPOLY)
                i += 1
            else:
                i += 1  # 避免死循环，跳过未知命令

        if verts:
            mpl_path = MplPath(verts, codes)
            patch = PathPatch(mpl_path, facecolor=fill_color, edgecolor='none')
            ax.add_patch(patch)


    ax.autoscale_view()
    plt.gca().invert_yaxis()
    plt.axis('off')


    filename = os.path.splitext(os.path.basename(svg_file))[0]
    output_path = os.path.join(output_folder, f"{filename}.png")
    plt.savefig(output_path, dpi=10, bbox_inches=None, pad_inches=0)
    plt.close()
    print(f"✅ 保存图像: {output_path}")

# ==============================
# 批量处理 SVG 文件夹中的所有文件
# ==============================

svg_folder = r"C:\Users\cenkai\Desktop\PCB_Detection\svg"  # 输入 SVG 文件夹路径
output_folder = r"C:\Users\cenkai\Desktop\PCB_Detection\output_full"  # 输出 PNG 路径

os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(svg_folder):
    if filename.lower().endswith(".svg"):
        svg_path = os.path.join(svg_folder, filename)
        process_svg(svg_path, output_folder)
